package com.broad.commerce.code.services.jdbc;

import com.broad.commerce.code.base.AbstractJavaService;
import com.broad.commerce.code.modules.BaseModule;
import com.broad.commerce.code.modules.jdbc.EntityModule;
import com.broad.commerce.common.utils.core.StringUtils;
import com.broad.commerce.web.exception.ServiceException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;

/**
 * @author stephen
 * @version V1.0
 * @date 2022-02-06 23:09
 * @description: ModuleService
 **/
@Service
public class EntityModuleService extends AbstractJavaService {
	/**
	 * package com.broad.commerce.jdbc.entity.pay;
	 * <br/>
	 * import com.broad.commerce.web.models.BaseIdEntity;
	 * import lombok.Getter;
	 * import lombok.NoArgsConstructor;
	 * import lombok.AllArgsConstructor;
	 * import lombok.Setter;
	 * import lombok.ToString;
	 * import javax.persistence.Entity;
	 * import javax.persistence.Table;
	 * import javax.persistence.Temporal;
	 * import javax.persistence.TemporalType;
	 * import java.math.BigDecimal;
	 * import java.util.Date;
	 * <br/>
	 * @Getter
	 * @Setter
	 * @ToString
	 * @Entity
	 * @NoArgsConstructor
	 * @AllArgsConstructor
	 * @Table(name = "PAY_INFO")
	 * public class PayInfo extends BaseIdEntity {
	 * private Long userId;//用户ID
	 * private String orderNo;//订单号
	 * private Integer payPlatform;//支付平台 1-支付宝,2-微信
	 * private String payNumber;//支付流水号
	 * private String payStatus;//支付状态
	 * private BigDecimal payAmount;//支付金额
	 * @Temporal(TemporalType.TIMESTAMP) <br/>
	 * private Date createTime;//创建时间
	 * @Temporal(TemporalType.TIMESTAMP) <br/>
	 * private Date updateTime;//更新时间
	 **/
	@Override
	public String createClassCode(BaseModule baseModule) {
		if (!(baseModule instanceof EntityModule)) {
			throw new ServiceException("传入参数类型错误！应为 EntityModule");
		}
		return super.createClassCode(baseModule);
	}

	@Override
	@SuppressWarnings("DuplicatedCode")
	public void createImportCode(StringBuilder sb, BaseModule baseModule) {
		EntityModule entityModule = (EntityModule) baseModule;
		boolean fieldExists = !CollectionUtils.isEmpty(entityModule.getEntityFields());
		//@off
		sb.append("import com.broad.commerce.jdbc.models.BaseIdEntity;").append("\n")
		  .append("import lombok.Builder;").append("\n")
		  .append("import lombok.Getter;").append("\n")
		  .append("import lombok.Setter;").append("\n")
		  .append("import lombok.experimental.Accessors;").append("\n")
		  .append("import lombok.NoArgsConstructor;").append("\n");//@on
		if (fieldExists) {
			sb.append("import lombok.AllArgsConstructor;").append("\n");
		}//@off
		sb.append("import lombok.ToString;").append("\n")
		  .append("\n").append("import javax.persistence.Column;").append("\n")
		  .append("import javax.persistence.Entity;").append("\n")
		  .append("import javax.persistence.Table;").append("\n");
		entityModule.getEntityFields().forEach(field -> {
			if (field.getFieldType() == Date.class && sb.indexOf("javax.persistence.Temporal") == -1) {
				sb.append("import javax.persistence.Temporal;").append("\n")
				  .append("import javax.persistence.TemporalType;").append("\n");
			}
			if (sb.indexOf(field.getFieldType().getName()) == -1) {
				sb.append("import ").append(field.getFieldType().getName()).append(";\n");
			}
		});
		sb.append("\n");//@on
	}

	@Override
	@SuppressWarnings("DuplicatedCode")
	public void createAnnotationCode(StringBuilder sb, BaseModule baseModule) {
		EntityModule entityModule = (EntityModule) baseModule;
		boolean fieldExists = !CollectionUtils.isEmpty(entityModule.getEntityFields());
		//@off
		sb.append("@Getter").append("\n")
		  .append("@Setter").append("\n")
		  .append("@ToString").append("\n")
		  .append("@Builder").append("\n")
		  .append("@Entity").append("\n")
		  .append("@NoArgsConstructor").append("\n");//@on
		if (fieldExists) {
			sb.append("@AllArgsConstructor").append("\n");
		}//@off
		sb.append("@Accessors(chain = true)").append("\n")
		  .append("@Table(name = ").append("\"").append(entityModule.getTableName().toUpperCase()).append("\")").append("\n");//@on
	}

	/**
	 * Create class start tag.
	 * @param sb the sb
	 * @param baseModule the base module
	 */
	@Override
	protected void createClassStartTag(StringBuilder sb, BaseModule baseModule) {
		EntityModule entityModule = (EntityModule) baseModule;
		sb.append("public class ").append(entityModule.getClassName()).append(" extends BaseIdEntity {").append("\n");
	}

	@Override
	@SuppressWarnings("DuplicatedCode")
	public void createClassContent(StringBuilder sb, BaseModule baseModule) {
		EntityModule entityModule = (EntityModule) baseModule;
		entityModule.getEntityFields().forEach(field -> {
			if (StringUtils.isNotEmpty(field.getFieldComment())) {
				sb.append("\t").append("// ").append(field.getFieldComment()).append("\n");
			}
			if (field.getFieldType() == Date.class) {
				sb.append("\t").append("@Temporal(TemporalType.TIMESTAMP)").append("\n");
			}
			if (field.getRequired() && field.getLength() > 0) {
				sb.append("\t").append("@Column(nullable = false, length = ").append(field.getLength()).append(")\n");
			} else if (field.getRequired() && field.getLength() == 0) {
				sb.append("\t").append("@Column(nullable = false)").append("\n");
			} else if (!field.getRequired() && field.getLength() > 0) {
				sb.append("\t").append("@Column(length = ").append(field.getLength()).append(")\n");
			}
			//@off
			sb.append("\t").append("private ").append(field.getFieldType().getSimpleName()).append(" ")
			  .append(field.getFieldName()).append(";\n");//@on
		});
	}
}
